package com.css.dzj.dzjap.modules.lawenforcesuper.service.impl;


import com.css.dzj.dzjap.common.util.*;
import com.css.dzj.dzjap.modules.info.entity.ApExpertEntity;
import com.css.dzj.dzjap.modules.info.service.ExpertService;
import com.css.dzj.dzjap.modules.lawenforcesuper.entity.*;
import com.css.dzj.dzjap.modules.lawenforcesuper.mapper.ApExpertRegulatorInfoMapper;
import com.css.dzj.dzjap.modules.lawenforcesuper.mapper.ApExtractExpertMapper;
import com.css.dzj.dzjap.modules.lawenforcesuper.service.ApExpertRegulatorService;
import com.css.dzj.dzjap.modules.lawenforcesuper.service.ExpregulatConnectExpertService;
import com.css.dzj.dzjap.sys.user.entity.LoginUser;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.querydsl.core.types.Predicate;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.UUID;


/**
 * 审查专家监管实现类
 * @author liyunyue
 */
@Service
public class ApExpertRegulatorServiceImpl implements ApExpertRegulatorService {


    @Autowired
    private ApExpertRegulatorInfoMapper regulatorInfoMapper;

    @Autowired
    private ApExtractExpertMapper apExtractExpertMapper;


    @Autowired
    private ExpertService expertService;

    @Autowired
    private ExpregulatConnectExpertService connectExpertService;

    @Autowired
    private JPAQueryFactory jpaQueryFactory;

    @Autowired
    private ServiceUtil serviceUtil;

    /**
     * 创建监管任务抽取专家
     * @param list
     */
    @Transactional
    @Override
    public R extract(ApExtractExpertEntity apExtractExpertEntity, List<ApExpertRegulatorInfoEntity> list, HttpServletRequest request) {
        try {
            if(StringUtils.isEmpty(apExtractExpertEntity) || StringUtils.isEmpty(list) || list.size() == 0) {
                throw new RuntimeException("抽取信息不能为空");
            }
            String createPerson = "";
            String location = "";
            String orgName = "";
            R r = serviceUtil.getUserInfoByRequest(request);
            if(r.getCode().equals("200")){
                LoginUser userInfo =  (LoginUser)r.get("data");
                if(StringUtils.isEmpty(userInfo) || StringUtils.isEmpty(userInfo.getLoginName()) || StringUtils.isEmpty(userInfo.getOrgName())) {
                    throw new RuntimeException("登录者信息不能为空!");
                }
                createPerson = userInfo.getLoginName();
                orgName = userInfo.getOrgName();
                location = userInfo.getOrgName().replace("地震局", "");
            }

            if(StringUtils.isEmpty(location)) {
                throw new RuntimeException("登录者地址不能为空！");
            }

            apExtractExpertEntity.setId(SnowflakeId.getId());
            apExtractExpertEntity.setLocation(orgName);
            apExtractExpertEntity.setCreatePerson(createPerson);
            apExtractExpertEntity.setCreateTime(new Date());
            apExtractExpertEntity.setDelFlag(Constant.NO_DELETE);
            apExtractExpertMapper.save(apExtractExpertEntity);

            // 遍历专家抽取信息
            for(ApExpertRegulatorInfoEntity apExpertRegulatorInfoEntity: list) {
                apExpertRegulatorInfoEntity.setCreateTime(new Date());
                apExpertRegulatorInfoEntity.setCreatePerson("");
                apExpertRegulatorInfoEntity.setDelFlag(Constant.NO_DELETE);
                apExpertRegulatorInfoEntity.setId(SnowflakeId.getId());
                apExpertRegulatorInfoEntity.setTaskId(apExtractExpertEntity.getId());

                regulatorInfoMapper.save(apExpertRegulatorInfoEntity);



                // 如果登录人为中国
                if("中国".equals(location)) {

                    if(apExpertRegulatorInfoEntity.getCountryRatio() + apExpertRegulatorInfoEntity.getProvinceRatio() != 100) {
                        throw new RuntimeException("抽取比例和必须为100");
                    }

                    // 实际抽取数量
                    int randomNum = 0;
                    double countryDouble = apExpertRegulatorInfoEntity.getCountryRatio()/100.0*apExpertRegulatorInfoEntity.getRegulatoryNum();
                    // 国家级需要抽取的人数
                    Integer countryNum = Integer.valueOf(new BigDecimal(countryDouble).setScale(0,BigDecimal.ROUND_HALF_UP).toString());
                    // 省级需要抽取的人数
                    Integer provinceNum = apExpertRegulatorInfoEntity.getRegulatoryNum() - countryNum;
                    List<ApExpertEntity> countryEntityList = expertService.listExpert(Constant.STATE_LEVEL, apExpertRegulatorInfoEntity.getMajor(), "", location, Constant.COUNTRYNO);
                    if((countryEntityList!= null && countryNum <= countryEntityList.size()) || (countryNum == 0 && countryEntityList == null) ) {
                        List<ApExpertEntity> ramdonCountryExtract = RandomUtil.ramdonExtract(countryEntityList, countryNum.toString());
                        if(ramdonCountryExtract != null && ramdonCountryExtract.size() > 0) {
                            for (ApExpertEntity apExpertEntity : ramdonCountryExtract) {
                                ExpregulatConnectExpertEntity connectExpertEntity = new ExpregulatConnectExpertEntity();
                                connectExpertEntity.setExpertId(apExpertEntity.getExpertId());
                                connectExpertEntity.setRegulatId(apExpertRegulatorInfoEntity.getId());
                                connectExpertEntity.setTaskId(apExtractExpertEntity.getId());
                                connectExpertEntity.setCqStatus(Constant.UNEXTRACT);
                                connectExpertEntity.setCreateTime(new Date());
                                connectExpertEntity.setCreatePerson("");
                                connectExpertService.save(connectExpertEntity);
                                randomNum++;
                            }
                        }

                    } else {
                        throw new RuntimeException("国家级专家人数不足！");
                    }

                    List<ApExpertEntity> provinceEntityList = expertService.listExpert(Constant.PROVIENCE_LEVEL, apExpertRegulatorInfoEntity.getMajor(), "", location, "");
                    if((provinceEntityList != null && provinceNum <= provinceEntityList.size()) || (provinceNum == 0 && provinceEntityList == null)) {
                        List<ApExpertEntity> randomProvinceExtract = RandomUtil.ramdonExtract(provinceEntityList, provinceNum.toString());
                        if(randomProvinceExtract != null && randomProvinceExtract.size() >0 ) {
                            for(ApExpertEntity apExpertEntity : randomProvinceExtract) {
                                ExpregulatConnectExpertEntity connectExpertEntity = new ExpregulatConnectExpertEntity();
                                connectExpertEntity.setRegulatId(apExpertRegulatorInfoEntity.getId());
                                connectExpertEntity.setExpertId(apExpertEntity.getExpertId());
                                connectExpertEntity.setTaskId(apExtractExpertEntity.getId());
                                connectExpertEntity.setCqStatus(Constant.UNEXTRACT);
                                connectExpertEntity.setCreateTime(new Date());
                                connectExpertEntity.setCreatePerson("");
                                connectExpertService.save(connectExpertEntity);
                                randomNum++;
                            }
                        }

                    } else {
                        throw new RuntimeException("省级专家人数不足！");
                    }

                    if(randomNum != apExpertRegulatorInfoEntity.getRegulatoryNum()) {
                        throw new RuntimeException("抽取数量不正确！");
                    }

                } else {

                    if(apExpertRegulatorInfoEntity.getCountryRatio() + apExpertRegulatorInfoEntity.getProvinceRatio() +
                        apExpertRegulatorInfoEntity.getOutProvinceRatio() != 100) {
                        throw new RuntimeException("抽取比例和必须为100");
                    }

                    int randomNum = 0;
                    /**
                     * 如果有两个0.5，第一个向上取整， 第二个向下取整
                     */
                    int upNum = 0;
                    Integer countryNum = 0;
                    Integer provinceNum = 0;
                    Integer outProvinceNum = 0;


                    double countryDouble = apExpertRegulatorInfoEntity.getCountryRatio()/100.0*apExpertRegulatorInfoEntity.getRegulatoryNum();
                 //   Integer countryInt = apExpertRegulatorInfoEntity.getCountryRatio()/100*apExpertRegulatorInfoEntity.getRegulatoryNum();
                    Integer countryInt = Integer.valueOf(new BigDecimal(countryDouble).setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());
                    if(upNum == 0) {
                        countryNum = Integer.valueOf(new BigDecimal(countryDouble).setScale(0,BigDecimal.ROUND_HALF_UP).toString());
                    } else {
                        countryNum = countryInt;
                    }
                    if(countryDouble - countryInt == 0.5) {
                        upNum++;
                    }

                    double provinceDouble = apExpertRegulatorInfoEntity.getProvinceRatio()/100.0*apExpertRegulatorInfoEntity.getRegulatoryNum();
                   // int provinceInt = apExpertRegulatorInfoEntity.getProvinceRatio()/100*apExpertRegulatorInfoEntity.getRegulatoryNum();
                    Integer provinceInt = Integer.valueOf(new BigDecimal(provinceDouble).setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());
                    if(upNum == 0) {
                        provinceNum = Integer.valueOf(new BigDecimal(provinceDouble).setScale(0 , BigDecimal.ROUND_HALF_UP ).toString());
                    } else {
                        provinceNum = provinceInt;
                    }
                    if(provinceDouble - provinceInt == 0.5) {
                        upNum++;
                    }

                    outProvinceNum = apExpertRegulatorInfoEntity.getRegulatoryNum() - countryNum - provinceNum;


                    List<ApExpertEntity> countryExperts = expertService.listExpert(Constant.STATE_LEVEL,apExpertRegulatorInfoEntity.getMajor(),"", location, "");
                    if((countryExperts!= null && countryNum <= countryExperts.size()) || (countryNum == 0 && countryExperts == null) ) {
                        List<ApExpertEntity> ramdonCountryExtract = RandomUtil.ramdonExtract(countryExperts, countryNum.toString());
                        if(ramdonCountryExtract != null && ramdonCountryExtract.size() > 0) {
                            for (ApExpertEntity apExpertEntity : ramdonCountryExtract) {
                                ExpregulatConnectExpertEntity connectExpertEntity = new ExpregulatConnectExpertEntity();
                                connectExpertEntity.setExpertId(apExpertEntity.getExpertId());
                                connectExpertEntity.setRegulatId(apExpertRegulatorInfoEntity.getId());
                                connectExpertEntity.setTaskId(apExtractExpertEntity.getId());
                                connectExpertEntity.setCqStatus(Constant.UNEXTRACT);
                                connectExpertEntity.setCreateTime(new Date());
                                connectExpertEntity.setCreatePerson("");
                                connectExpertService.save(connectExpertEntity);
                                randomNum++;
                            }
                        }

                    } else {
                        throw new RuntimeException("国家级专家人数不足！");
                    }

                    List<ApExpertEntity> provinceExperts = expertService.listExpert(Constant.PROVIENCE_LEVEL,apExpertRegulatorInfoEntity.getMajor(),"", location, Constant.PROVIENCEIN);
                    if((provinceExperts != null && provinceNum <= provinceExperts.size()) || (provinceNum == 0 && provinceExperts == null)) {
                        List<ApExpertEntity> randomProvinceExtract = RandomUtil.ramdonExtract(provinceExperts, provinceNum.toString());
                        if(randomProvinceExtract != null && randomProvinceExtract.size() >0 ) {
                            for(ApExpertEntity apExpertEntity : randomProvinceExtract) {
                                ExpregulatConnectExpertEntity connectExpertEntity = new ExpregulatConnectExpertEntity();
                                connectExpertEntity.setRegulatId(apExpertRegulatorInfoEntity.getId());
                                connectExpertEntity.setExpertId(apExpertEntity.getExpertId());
                                connectExpertEntity.setTaskId(apExtractExpertEntity.getId());
                                connectExpertEntity.setCqStatus(Constant.UNEXTRACT);
                                connectExpertEntity.setCreateTime(new Date());
                                connectExpertEntity.setCreatePerson("");
                                connectExpertService.save(connectExpertEntity);
                                randomNum++;
                            }
                        }

                    } else {
                        throw new RuntimeException("省内专家人数不足！");
                    }

                    List<ApExpertEntity> outProvinceExperts = expertService.listExpert(Constant.PROVIENCE_LEVEL,apExpertRegulatorInfoEntity.getMajor(),"", location, Constant.PROVIENCEOUT);
                    if((outProvinceExperts != null && outProvinceNum <= outProvinceExperts.size()) || (outProvinceNum == 0 && outProvinceExperts == null)) {
                        List<ApExpertEntity> randomOutProvinceExtract = RandomUtil.ramdonExtract(outProvinceExperts, outProvinceNum.toString());
                        if(randomOutProvinceExtract != null && randomOutProvinceExtract.size() >0) {
                            for(ApExpertEntity apExpertEntity : randomOutProvinceExtract) {
                                ExpregulatConnectExpertEntity connectExpertEntity = new ExpregulatConnectExpertEntity();
                                connectExpertEntity.setExpertId(apExpertEntity.getExpertId());
                                connectExpertEntity.setRegulatId(apExpertRegulatorInfoEntity.getId());
                                connectExpertEntity.setTaskId(apExtractExpertEntity.getId());
                                connectExpertEntity.setCqStatus(Constant.UNEXTRACT);
                                connectExpertEntity.setCreateTime(new Date());
                                connectExpertEntity.setCreatePerson("");
                                connectExpertService.save(connectExpertEntity);
                                randomNum++;
                            }
                        }

                    } else {
                        throw new RuntimeException("省外专家人数不足！");
                    }

                    if(randomNum != apExpertRegulatorInfoEntity.getRegulatoryNum()) {
                        throw new RuntimeException("抽取数量不正确！");
                    }

                }

            }
            return R.ok("抽取成功！").put("taskId", apExtractExpertEntity.getId());

        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }

    }


    /**
     * 分页查询所有专家任务
     * @param pageable
     * @param title
     * @return
     */
    @Override
    public QueryResults<ApExtractExpertEntity> queryAll(Pageable pageable, String title, HttpServletRequest request) {
        String orgName = "";
        R r = serviceUtil.getUserInfoByRequest(request);
        if(r.getCode().equals("200")){
            LoginUser userInfo =  (LoginUser)r.get("data");
            if(StringUtils.isEmpty(userInfo) || StringUtils.isEmpty(userInfo.getLoginName()) || StringUtils.isEmpty(userInfo.getOrgName())) {
                throw new RuntimeException("登录者信息不能为空!");
            }
            orgName = userInfo.getOrgName();
        }

        if(StringUtils.isEmpty(orgName)) {
            throw new RuntimeException("登录者地址不能为空！");
        }

        QApExtractExpertEntity qApExtractExpertEntity = QApExtractExpertEntity.apExtractExpertEntity;

        Predicate predicate = qApExtractExpertEntity.isNotNull().or(qApExtractExpertEntity.isNull());
        predicate = ("".equals(title) || title == null) ? predicate : ExpressionUtils.and(predicate, qApExtractExpertEntity.title.like("%"+title+"%"));
        predicate = ExpressionUtils.and(predicate, qApExtractExpertEntity.location.eq(orgName));
        predicate = ExpressionUtils.and(predicate, qApExtractExpertEntity.delFlag.eq(Constant.NO_DELETE));
        return jpaQueryFactory
                .selectFrom(qApExtractExpertEntity)
                .where(predicate)
                .orderBy(qApExtractExpertEntity.createTime.desc())
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetchResults();
    }

    /**
     * 通过id获取
     * @param regulatId
     * @return
     */
    @Override
    public ApExpertRegulatorInfoEntity queryById(String regulatId) {
        return regulatorInfoMapper.findById(regulatId).get();
    }

    /**
     * 通过任务id获取所有专家抽取条件信息
     * @param taskId
     * @return
     */
    @Override
    public List<ApExpertRegulatorInfoEntity> queryRegulatorByTaskId(String taskId) {
        QApExpertRegulatorInfoEntity qRegulatorInfoEntity = QApExpertRegulatorInfoEntity.apExpertRegulatorInfoEntity;
        return jpaQueryFactory.selectFrom(qRegulatorInfoEntity)
                .where(qRegulatorInfoEntity.taskId.eq(taskId), qRegulatorInfoEntity.delFlag.eq(Constant.NO_DELETE)).fetch();

    }


}
